package edu.gatech.coc.sirana.parser;

import java.util.ArrayList;
import java.util.StringTokenizer;

import edu.gatech.coc.sirana.exception.SIRANAException;
import edu.gatech.coc.sirana.graph.InteractionCycle;
import edu.gatech.coc.sirana.util.CONSTANT;

import net.util.Debug;

public class ClientLogItem implements Comparable<ClientLogItem>{
/**
 * This class parse a client log item. 
 * Example: [1259003539130] [Monday, November 23, 2009 2:12:19 PM] focus [/demo/login.php] [email_address|INPUT|text][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][login|FORM][-|TD][-|TR][-|TBODY][-|TABLE][-|BODY][-|HTML][-|-]
 * 
 * [-|INPUT|image|http://www.gatechmedical.com/demo/includes/languages/english/images/buttons/button_in_cart.gif][-|TD][-|TR][-|TBODY][-|TABLE][cart_quantity|FORM][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|BODY][-|HTML][-|-]
 * 
 */
//	public static void main(String[] args){
//		String item	= "[1258563664518] [Wednesday, November 18, 2009 12:01:04 PM] click [/demo/checkout_success.php] [-|<img src=\"images/categories/arrow_right.gif\" border=\"0\">Nebulizers|http://www.gatechmedical.com/demo/compressor-ultrasonic-nebulizer-c-45.html][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|BODY][-|HTML][-|-]"; 
//			//"[1259003539130] [Monday, November 23, 2009 2:12:19 PM] focus [demo.login.php]";// [email_address|INPUT|text][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][-|TD][-|TR][-|TBODY][-|TABLE][login|FORM][-|TD][-|TR][-|TBODY][-|TABLE][-|BODY][-|HTML][-|-]";
//		
//		ClientLogItem c = new ClientLogItem(item);
//	}
	
	private int id;//serial number
	private String timeStamp;
	private String time;
	private String event;
	private String page;
	private String value;
	private String type;
			
	public ClientLogItem(String logItem){
		this.doParse(logItem);
	}

	public String findAction(){
		StringBuffer sb = new StringBuffer(this.event + " [" + this.page + "]");
//		Debug.println( "findAction: " + this.toString());
		sb.append(findPreciseValue());
		return sb.toString();
	}
	
	public String findIDString(){
		StringBuffer sb = new StringBuffer(this.event.trim() + "-");
		
		sb.append(getType());
		
		return sb.toString();
	}
	
	
	private String findPreciseValue(){
		if (this.value == null) return "";
						
		String value= this.getValue();	
		
		int iHttp = value.indexOf("http://");
		int iTxt = value.indexOf("|INPUT|text");
		
		if ( iHttp > 0 ){
			String httpValue =value.substring(iHttp);
			value = httpValue.substring(0, httpValue.indexOf("]"));
		}else if (iTxt > 0){
			value = value.substring(0, iTxt) + "|INPUT|text]";
		}
		
		return value;
	}
	
	private String parseInputType(String input){	
		String inputType = null;
		StringTokenizer st = new StringTokenizer(input, "|");
		while(st.hasMoreTokens()){
			String token = st.nextToken();
//			Debug.println("TOKENING: " + token );
			if (token.equals(CONSTANT.INPUT_TYPE)) {
				inputType =st.nextToken();
				
				int iBackbracket = inputType.indexOf("]");
				if (iBackbracket > 0)
					inputType = inputType.substring(0, iBackbracket);
				break;
			}
		}
	
		if (inputType == null)
			throw new SIRANAException("Not an input type: " + input);
		
//		Debug.print("from " + input );
//		Debug.println("\n\tget paresed input type is " + inputType );
		return inputType;		
	}
	
	private void doParse(String logItem){
//		Debug.println("--parse log item\n\t" + logItem);
		String ts		= logItem.substring(logItem.indexOf('[')+1, logItem.indexOf(']'));
		String restTS	= logItem.substring(logItem.indexOf(']')+1);
		
//		Debug.print("--ts: " + ts);
//		Debug.println("\nrestTS: " + restTS);
		
		String t	= restTS.substring(restTS.indexOf('[')+1, restTS.indexOf(']'));
		String restT= restTS.substring(restTS.indexOf(']'));
		
//		Debug.print("--t: " + t);
//		Debug.println("\nrestT: " + restT);
		
		String a	= restT.substring(1, restT.indexOf('['));
		String restA= restT.substring(restT.indexOf('[')).trim();
		
//		Debug.print("--a: " + a);
//		Debug.println("\nrestA: " + restA);
		
		String p	= restA.substring(restA.indexOf('[')+1, restA.indexOf(']'));
		String v	= restA.substring(restA.indexOf(']')+1);
		
//		Debug.println("--ts: " + ts);
//		Debug.println("--t: " + t);
//		Debug.println("--a: " + a);
//		Debug.println("--p: " + p);
//		Debug.println("--v: " + v);
		
		this.setTimeStamp(ts.trim());
		this.setTime(t.trim());
		this.setEvent(a.trim());
		this.setPage(p.trim());
		if (v.trim().length() > 1)
			this.setValue(v.trim());
		
		this.setId(CONSTANT.NOT_SIGNED_ID);

		int iHttp = v.indexOf("http://");
		int iInput = v.indexOf(CONSTANT.INPUT_TYPE);
		if (isImgType(v)) setType(CONSTANT.IMAGE_TYPE);
		else if (iHttp > 0) setType(CONSTANT.HTTP_TYPE);
		else if (iInput > 0) setType(this.parseInputType(v.trim()));
	}
	
	public boolean isImgType(String v){
		if (v.indexOf(CONSTANT.image) > 0 ||
				v.indexOf(CONSTANT.IMAGE) > 0 ||
				v.indexOf(CONSTANT.img) > 0 ||
				v.indexOf(CONSTANT.IMG) > 0)
		return true;
		else return false;
	}
	
	public boolean isSameAction(ClientLogItem c){
		return this.findAction().equalsIgnoreCase(c.findAction());
	}

	public boolean isSameTime(ClientLogItem c){
		return this.getTime().equals(c.getTime());
	} 
	
	public boolean isSameEvent(ClientLogItem c){
		return this.getEvent().equalsIgnoreCase(c.getEvent());
	}
	
	public boolean isSamePage(ClientLogItem c){
		return this.getPage().equalsIgnoreCase(c.getPage());
	}
	
	public boolean hasInteractiveEvent(){	
//		return (!this.isEnterEvent() && !this.isLeaveEvent() && !this.isTextarea() && !this.isTextfield());
		return this.isClickEvent() && !this.isTextarea() &&!this.isTextfield();
	}
	
	public boolean isLeaveEvent(){
		return this.getEvent().equalsIgnoreCase(CONSTANT.EVENT_LEAVE);
	}
	
	public boolean isEnterEvent(){
		return this.getEvent().equalsIgnoreCase(CONSTANT.EVENT_ENTER);
	}
	
	public boolean isClickEvent(){
		return this.getEvent().equalsIgnoreCase(CONSTANT.EVENT_CLICK);
	}
	
	public boolean isTextarea(){
		if (this.getValue()==null) return false;
		return this.getValue().contains(CONSTANT.TEXTAREA);
	}
		
	public boolean isTextfield(){
		if (this.getValue()==null) return false;
		return this.getValue().contains(CONSTANT.TEXTFIELD);
	}
	
	public String getTimeStamp() {
		return timeStamp;
	}

	public void setTimeStamp(String timeStamp) {
		this.timeStamp = timeStamp;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getEvent() {
		return event;
	}

	public void setEvent(String action) {
		this.event = action;
	}

	public String getPage() {
		return page;
	}

	public void setPage(String pg) {
		if (pg.endsWith("index.php"))
			pg = pg.substring(0, pg.indexOf("index.php"));
		this.page = pg;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
	
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	public void setType(String t){
		this.type = t;
	}
	
	public String getType(){
		return this.type;
	}

	public String toString(){
		StringBuffer sb = new StringBuffer();
		
		sb.append(id + " [" +this.timeStamp + "] [" + this.time + "] " + this.event + " [" + this.page + "] " );
		
		if (this.value!=null) sb.append( value );
		
//		sb.append("\n");
		
		return sb.toString();
	}

	@Override
	public int compareTo(ClientLogItem c) {
		return this.getTimeStamp().compareTo(c.getTimeStamp());
	}
	
}
